package mall

import (
	"errors"
	"fmt"
	"time"

	"gorm.io/gorm"
	"main.go/global"
	"main.go/model/mall"
	mallReq "main.go/model/mall/request"
	"main.go/utils"
)

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Register
//@description: 用户注册
//@param: u model.SysUser
//@return: userInter system.SysUser, err error

type UserService struct{}

func (s *UserService) Login(req *mallReq.MallUserReq) (out *mall.MallUser, err error) {
	var user mall.MallUser
	err = global.EVA_DB.Where("mobile = ?", req.Mobile).First(&user).Error
	if err == nil {
		if ok := utils.BcryptCheck(req.Password, user.Password); !ok {
			return nil, errors.New("密码错误")
		}
	}
	return &user, err
}

func (s *UserService) ChangePassword(req *mall.MallUser, newPassword string) (out *mall.MallUser, err error) {
	var user mall.MallUser
	if err = global.EVA_DB.Where("id = ?", req.ID).First(&user).Error; err != nil {
		return nil, err
	}
	if ok := utils.BcryptCheck(req.Password, user.Password); !ok {
		return nil, errors.New("原密码错误")
	}
	password := utils.BcryptHash(newPassword)
	err = global.EVA_DB.Model(&mall.MallUser{}).Select("password").Where(map[string]interface{}{"mobile": req.Mobile}).Updates(map[string]interface{}{"password": password}).Error
	return &user, err
}

func (s *UserService) ResetPassword(ID uint) (err error) {
	err = global.EVA_DB.Model(&mall.MallUser{}).Where("id = ?", ID).Update("password", utils.BcryptHash("123456")).Error
	return err
}

func (s *UserService) IsExitMobile(u *mall.MallUser) (out *mall.MallUser, err error) {
	err = global.EVA_DB.Where("mobile = ?", u.Mobile).First(&out).Error
	return out, err
}

func (s *UserService) Create(u *mall.MallUser) (out *mall.MallUser, err error) {
	var user mall.MallUser
	if !errors.Is(global.EVA_DB.Where("mobile = ?", u.Mobile).First(&user).Error, gorm.ErrRecordNotFound) { // 判断用户名是否注册
		return out, errors.New("手机号名已注册")
	}
	u.UUID = utils.GenerateUUID()
	// 否则 附加uuid 密码hash加密 注册
	u.Password = utils.BcryptHash(u.Password)
	err = global.EVA_DB.Create(&u).Error
	return u, err
}

func (s *UserService) Delete(id int) (err error) {
	// 事务
	return global.EVA_DB.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("id = ?", id).Delete(&mall.MallUser{}).Error; err != nil {
			return err
		}
		return nil
	})
}

func (s *UserService) Update(req mall.MallUser) (out mall.MallUser, err error) {
	updateData := make(map[string]interface{})
	if len(req.NickName) > 0 {
		updateData["nick_name"] = req.NickName
	}
	if len(req.Avatar) > 0 {
		updateData["avatar"] = req.Avatar
	}
	if len(req.Email) > 0 {
		updateData["email"] = req.Email
	}
	if req.Enable != nil {
		updateData["enable"] = req.Enable
	}

	err = global.EVA_DB.Model(&mall.MallUser{}).Where(mall.MallUser{
		EVA_MODEL: global.EVA_MODEL{
			ID: req.ID,
		},
	}).Updates(updateData).Error
	return out, err
}

func (s *UserService) List(req *mallReq.MallUserListReq) (list []mall.MallUser, total int64, err error) {
	limit := req.PageSize
	offset := req.PageSize * (req.Page - 1)
	fmt.Println(limit, offset)
	db := global.EVA_DB.Model(&mall.MallUser{})
	// 如果有条件搜索 下方会自动创建搜索语句
	if len(req.NickName) != 0 {
		db = db.Where("nick_name LIKE ?", "%"+req.NickName+"%")
	}
	if len(req.Mobile) != 0 {
		db = db.Where("mobile LIKE ?", "%"+req.Mobile+"%")
	}
	if len(req.Email) != 0 {
		db = db.Where("email LIKE ?", "%"+req.Email+"%")
	}
	if req.ID != 0 {
		db = db.Where("id = ?", req.ID)
	}
	if req.Enable != nil {
		db = db.Where("enable = ?", req.Enable)
	}
	if req.StartCreatedAt != 0 && req.EndCreatedAt != 0 {
		t1 := time.Unix(req.StartCreatedAt, 0).In(utils.ShLocation)
		t2 := time.Unix(req.EndCreatedAt, 0).In(utils.ShLocation)
		db = db.Where("created_at BETWEEN ? AND ?", t1, t2)
	}
	err = db.Count(&total).Error
	if err != nil {
		return list, total, err
	}

	err = db.Order("id desc").Limit(limit).Offset(offset).Find(&list).Error
	return list, total, err
}

func (s *UserService) UserInfo(userId uint) (user *mall.MallUser, err error) {
	var reqUser *mall.MallUser
	err = global.EVA_DB.First(&reqUser, "id = ?", userId).Error
	if err != nil {
		return reqUser, err
	}
	return reqUser, err
}
